﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Web.Http.ValueProviders;
using MongoDB.Bson;
using PicShare.Server.Attributes;
using PicShare.Server.Helpers;
using PicShare.Server.Models;
using PicShare.Server.Repositories;

namespace PicShare.Server.Controllers
{
    public class ImageController : BaseApiController
    {

        private readonly IRepository<User> _repository;

        public ImageController(IRepository<User> repository)
        {
            this._repository = repository;
        }

        [ActionName("load-albums")]
        public HttpResponseMessage GetLoadUserAlbums(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMesg = this.PerformOperationAndHandleExceptions(
             () =>
             {
                 var users = _repository.GetAll();

                 HttpResponseMessage response = null;
                 var usersWithAlbumNames = new List<UserWithAlbumNames>();

                 if (users != null)
                 {
                     foreach (var user in users.ToList())
                     {
                         Dictionary<string, List<BsonObjectId>> currentDict = user.Albums;
                         if (currentDict != null)
                         {
                             var usr = new UserWithAlbumNames()
                             {
                                 NickName = user.UserName,
                                 AlbumNames = currentDict.Keys.ToList()
                             };
                             usersWithAlbumNames.Add(usr);
                         }

                     }
                     response = this.Request.CreateResponse(HttpStatusCode.OK, usersWithAlbumNames);
                 }
                 else
                 {
                     response = this.Request.CreateErrorResponse(HttpStatusCode.NotModified, "Not loaded");
                 }
                 return response;
             });

            return responseMesg;

        }

        [ActionName("next-images")]
        public HttpResponseMessage GetNextImagesFromAlbums(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey, string albumName)
        {/*
            var responseMesg = this.PerformOperationAndHandleExceptions(
             () =>
             {
                 var user = _repository.Find(usr => usr.SessionKey == sessionKey);

                 HttpResponseMessage response = null;

                 if (user != null)
                 {
                     user.SessionKey = null;
                     _repository.Update(user);
                     response = this.Request.CreateResponse(HttpStatusCode.OK, "User Logged Out");
                 }
                 else
                 {
                     response = this.Request.CreateErrorResponse(HttpStatusCode.NotModified, "User Did Not Logged Out");
                 }
                 return response;
             });

            return responseMesg;
          */
            return null;
        }

        [ActionName("add-image")]
        public HttpResponseMessage PostAddImageToUser(string userName, string albumName)
        {
            var responseMesg = this.PerformOperationAndHandleExceptions(
           () =>
           {
               var httpRequest = HttpContext.Current.Request;
               object fileInfo = null;
               HttpResponseMessage response = null;

               foreach (string file in httpRequest.Files)
               {
                   var postedFile = httpRequest.Files[file];

                   if (postedFile == null) continue;
                   using (var stream = postedFile.InputStream)
                   {
                       fileInfo = ((UsersRepository)_repository).AddFile(stream, "");
                   }
               }

               var searchedUser = _repository.Find(usr => usr.UserName == userName);

               if (searchedUser != null && searchedUser.Albums == null)
               {
                   var dictionary = new Dictionary<string, List<BsonObjectId>>();
                   dictionary.Add(albumName, new List<BsonObjectId>() { (BsonObjectId)fileInfo });
                   searchedUser.Albums = dictionary;
                   _repository.Update(searchedUser);
                   response = this.Request.CreateResponse(HttpStatusCode.OK, "Image Uploaded");
               }
               else if (searchedUser != null && searchedUser.Albums != null)
               {
                   if (searchedUser.Albums.ContainsKey(albumName))
                   {
                       searchedUser.Albums[albumName].Add((BsonObjectId)fileInfo);
                       _repository.Update(searchedUser);
                       response = this.Request.CreateResponse(HttpStatusCode.OK, "Image Uploaded");
                   }
                   else
                   {
                       searchedUser.Albums.Add(albumName, new List<BsonObjectId>() { (BsonObjectId)fileInfo });
                       _repository.Update(searchedUser);
                       response = this.Request.CreateResponse(HttpStatusCode.OK, "Image Uploaded");
                   }
               }

               return response;
           });
            return responseMesg;
        }

        [ActionName("remove-image")]
        public HttpResponseMessage PutRemoveImage(string userName, string albumName)
        {
            return null;
        }

        [ActionName("load-users-albums")]
        public HttpResponseMessage GetLoadUsersAndAlbums(string userName)
        {
            var responseMesg = this.PerformOperationAndHandleExceptions(
              () =>
              {
                  var user = _repository.Find(usr => usr.UserName == userName);

                  HttpResponseMessage response = null;

                  if (user != null)
                  {
                      var usersWithAlbumNames = new List<UserWithAlbumNames>();

                      foreach (var item in _repository.GetAll())
                      {
                          var currentUserWithAlbums = new UserWithAlbumNames();

                          if (item.Albums != null)
                          {
                              currentUserWithAlbums.NickName = item.UserName;
                              currentUserWithAlbums.AlbumNames = (from alb in item.Albums
                                                                  select alb.Key).ToList();
                          }
                          else
                          {
                              currentUserWithAlbums.NickName = item.UserName;
                              currentUserWithAlbums.AlbumNames = null;
                          }
                          usersWithAlbumNames.Add(currentUserWithAlbums);
                      }

                      response = this.Request.CreateResponse(HttpStatusCode.OK, usersWithAlbumNames);
                  }
                  else
                  {
                      response = this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Albums Not Loaded");
                  }
                  return response;
              });

            return responseMesg;
        }

        [ActionName("test-load-images")]
        public HttpResponseMessage GetTestLoadImages(string userName)
        {
            var responseMesg = this.PerformOperationAndHandleExceptions(
              () =>
              {
                  var user = _repository.Find(usr => usr.UserName == userName);

                  HttpResponseMessage response = null;
                  var imagesAsStringList = new List<string>();

                  if (user != null)
                  {
                      foreach (var album in user.Albums)
                      {
                          var currentAlbum = album.Value;

                          for (int i = 0; i < currentAlbum.Count(); i++)
                          {
                              var file = ((UsersRepository)_repository).GetFile(currentAlbum[i]);
                              using (var binaryReader = new BinaryReader(file.OpenRead()))
                              {
                                  var userImageByteArray = binaryReader.ReadBytes((int)file.Length);
                                  var image = Convert.ToBase64String(userImageByteArray);
                                  imagesAsStringList.Add(image);
                              }
                          }
                      }

                      response = this.Request.CreateResponse(HttpStatusCode.OK, imagesAsStringList);
                  }
                  else
                  {
                      response = this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Albums Not Loaded");
                  }
                  return response;
              });

            return responseMesg;
        }

        [ActionName("load-images-from-album")]
        public HttpResponseMessage GetLoadImagesFromAlbum(string userName, string albumName, int counter, int itemsCount)
        {
            var responseMesg = this.PerformOperationAndHandleExceptions(
              () =>
              {
                  var user = _repository.Find(usr => usr.UserName == userName);
                  HttpResponseMessage response = null;
                  var imageModelList = new List<ReturnedImageModel>();

                  if (user != null)
                  {
                      var userAlbum = user.Albums.First(alb => alb.Key == albumName).Value.ToList();
                      var images = userAlbum.Skip(counter).Take(itemsCount);

                      foreach (var image in images)
                      {
                          var file = ((UsersRepository)_repository).GetFile(image);

                          using (var binaryReader = new BinaryReader(file.OpenRead()))
                          {
                              var userImageByteArray = binaryReader.ReadBytes((int)file.Length);
                              var convertedPic = Convert.ToBase64String(userImageByteArray);

                              var imgObj = new ReturnedImageModel
                              {
                                  Src = convertedPic,
                                  Index = userAlbum.IndexOf(image)
                              };

                              imageModelList.Add(imgObj);
                          }
                      }

                      var requestedImages = new
                      {
                          albumLength = userAlbum.Count(),
                          images = imageModelList
                      };

                      response = this.Request.CreateResponse(HttpStatusCode.OK, requestedImages);
                  }
                  else
                  {
                      response = this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Albums Not Loaded");
                  }
                  return response;
              });

            return responseMesg;
        }


       [ActionName("delete-image")]
       public HttpResponseMessage PostDeleteImage(string userName,string albumName,int index)
       {

           var responseMesg = this.PerformOperationAndHandleExceptions(
            () =>
            {
                var albumsPicture = new List<List<ReturnedImageModel>>();
                var user = _repository.Find(usr => usr.UserName == userName);
                HttpResponseMessage response = null;
                if (user != null)
                {
                    ((UsersRepository) _repository).DeleteFile(userName,albumName,index);
                   
                    response = this.Request.CreateResponse(HttpStatusCode.OK, "Deleted");
                }
                else
                {
                    response = this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Albums Not Loaded");
                }
                return response;
            });

           return responseMesg;

       }
        [ActionName("load-user-images")]
        public HttpResponseMessage PostLoadUserImages(string userName, int counter, int itemsCount, string[] albumNames)
        {

            var responseMesg = this.PerformOperationAndHandleExceptions(
             () =>
             {
                
                 var albumsPicture = new Dictionary<string, List<ReturnedImageModel>>();
                 var user = _repository.Find(usr => usr.UserName == userName);
                 HttpResponseMessage response = null;
                 if (user != null)
                 {
                     foreach (string albName in albumNames)
                     {
                         var userAlbum = user.Albums.First(alb => alb.Key == albName).Value.ToList();
                         var images = userAlbum.Skip(counter).Take(itemsCount);
                         var imageModelList = new List<ReturnedImageModel>();

                         foreach (var image in images)
                         {
                             var file = ((UsersRepository)_repository).GetFile(image);

                             using (var binaryReader = new BinaryReader(file.OpenRead()))
                             {
                                 var userImageByteArray = binaryReader.ReadBytes((int)file.Length);
                                 var convertedPic = Convert.ToBase64String(userImageByteArray);

                                 var imgObj = new ReturnedImageModel
                                 {
                                     Src = convertedPic,
                                     Index = userAlbum.IndexOf(image),
                                     AlbumName = albName
                                 };

                                 imageModelList.Add(imgObj);
                             }
                         }

                         albumsPicture.Add(albName,imageModelList);
                     }

                     response = this.Request.CreateResponse(HttpStatusCode.OK, albumsPicture);
                 }
                 else
                 {
                     response = this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Albums Not Loaded");
                 }
                 return response;
             });

            return responseMesg;

        }
    }
}
